package searchkeyword

import (
	"context"
	"fmt"
	"strings"
	"time"

	"mall/common/globalkey"
	"mall/common/modelx"
	"mall/common/resultx"
	"mall/common/utils/pointy"
	"mall/service/backend/model"
	"mall/service/backend/rpc/internal/svc"
	"mall/service/backend/rpc/internal/utils/errorhandler"
	"mall/service/backend/rpc/types/backend"

	"github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/logx"
)

type GetSearchKeywordByIdLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewGetSearchKeywordByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetSearchKeywordByIdLogic {
	return &GetSearchKeywordByIdLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *GetSearchKeywordByIdLogic) GetSearchKeywordById(in *backend.BaseIdReq) (*backend.SearchKeywordInfo, error) {
	logrus.Info(fmt.Sprintf("GetSearchKeywordById BaseIdReq: %+v", in))
	//
	if (in.Filter == nil || len(*in.Filter) == 0) && (in.Id == nil || *in.Id == 0) {
		return nil, resultx.StatusError(resultx.REUQEST_PARAM_ERROR, "")
	}

	preloadMap, _ := modelx.ParsePreloadAndEagerLoad(in.Preload, in.EagerLoad)
	logrus.Info(fmt.Sprintf("GetSearchKeywordById preloadMap: %+v", preloadMap))
	//

	resp := &backend.SearchKeywordInfo{}

	searchKeywordEntityName := model.RpcEntityNames.SearchKeyword
	if _, ok := model.RpcEntityPreloadMap[searchKeywordEntityName]; !ok {
		return resp, nil
	}

	searchKeywordRepositoryName := model.RepositoryNames.SearchKeyword
	columnMap, ok := model.RepositoryPreloadMap[searchKeywordRepositoryName]
	if !ok {
		return resp, nil
	}

	var searchKeyword *model.SearchKeyword
	if in.Id != nil && *in.Id > 0 {
		data, err := l.svcCtx.SearchKeyword.FindOne(l.ctx, *in.Id)
		if err != nil {
			return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
		}
		searchKeyword = data
	} else {
		//select
		var selectCols []string
		if preloadFields, ok := preloadMap[searchKeywordEntityName]; ok {
			selectCols = modelx.ParseSelectColumns(preloadFields, columnMap)
		}
		// filterMap map[string]map[string][]any
		filterMap := modelx.ParseFilter(in.Filter, columnMap)
		logrus.Info(fmt.Sprintf("GetSearchKeywordById filterMap: %+v", filterMap))
		//
		if filterMap == nil {
			return nil, resultx.StatusError(resultx.REUQEST_PARAM_ERROR, "")
		}
		//order
		orderBy := modelx.ParseSorter(in.Sorter, columnMap)
		logrus.Info(fmt.Sprintf("GetSearchKeywordById orderBy: %s", orderBy))

		if len(orderBy) == 0 {
			orderBy = model.SearchKeywordColumns.ID
		}

		res, _, err := l.svcCtx.SearchKeyword.GetList(l.ctx, model.M{
			"pageSize": uint64(1),
			"orderBy":  orderBy,
			"select":   strings.Join(selectCols, ","),
		}, -1, filterMap)
		if err != nil {
			return nil, err
		}

		if len(res) == 0 {
			return resp, nil
		}

		searchKeyword = res[0]
	}
	if searchKeyword == nil {
		return resp, nil
	}
	if searchKeyword.Status != uint8(globalkey.StatusEnabled) {
		return resp, nil
	}
	now := time.Now()
	if searchKeyword.StartedAt.Valid && searchKeyword.StartedAt.Time.After(now) {
		return resp, nil
	}

	if searchKeyword.EndedAt.Valid && searchKeyword.EndedAt.Time.Before(now) {
		return resp, nil
	}

	var sort *uint32
	if searchKeyword.Sort != uint16(globalkey.SystemDefaultSort) {
		sort = pointy.GetPointer(uint32(searchKeyword.Sort))
	}
	return &backend.SearchKeywordInfo{
		Id:         pointy.GetPointer(searchKeyword.ID),
		Type:       pointy.GetPointer(uint32(searchKeyword.Type)),
		Title:      pointy.GetPointer(searchKeyword.Title),
		ObjectId:   pointy.GetPointer(searchKeyword.ObjectID),
		ObjectType: pointy.GetPointer(uint32(searchKeyword.ObjectType)),
		LinkType:   pointy.GetPointer(uint32(searchKeyword.LinkType)),
		LinkUrl:    pointy.GetPointer(searchKeyword.LinkURL),
		Sort:       sort,
		Status:     pointy.GetPointer(uint32(searchKeyword.Status)),
		CreatedAt:  pointy.GetPointer(modelx.FormatTime(searchKeyword.CreatedAt, "")),
		UpdatedAt:  pointy.GetPointer(modelx.FormatTime(searchKeyword.UpdatedAt, "")),
		DeletedAt:  pointy.GetPointer(modelx.FormatNullDotTime(searchKeyword.DeletedAt, "")),
		StartedAt:  pointy.GetPointer(modelx.FormatNullDotTime(searchKeyword.StartedAt, "")),
		EndedAt:    pointy.GetPointer(modelx.FormatNullDotTime(searchKeyword.EndedAt, "")),
	}, nil
}
